package com.aegis.sdk.signature.utils;


import com.aegis.sdk.signature.exceptions.SignatureException;
import com.aegis.sdk.signature.model.SignatureParams;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author wuweixin
 *
 * @Version 1.0
 * @Descritube
 */
public class SignatureUtil {


    /**
     * 生成签名
     *
     * @param signatureParams 签名请求参数对象
     * @param secret          签名密钥
     * @return 计算出的签名
     */
    public static String generateSignature(SignatureParams signatureParams, String secret) {
        if (isStringBlank(signatureParams.getAppId())) {
            throw new SignatureException("appId不能为空");
        }
        if (isStringBlank(signatureParams.getNonce())) {
            throw new SignatureException("nonce不能为空");
        }
        if (isStringBlank(signatureParams.getTimestamp())) {
            throw new SignatureException("timestamp不能为空");
        }
        Map<String, String> sortedParams = new LinkedHashMap<>();
        sortedParams.put("appId", signatureParams.getAppId());
        sortedParams.put("nonce", signatureParams.getNonce());
        sortedParams.put("timestamp", signatureParams.getTimestamp());
        sortedParams.put("token", signatureParams.getToken());
        sortedParams.put("query", signatureParams.getQuery());
        sortedParams.put("body", signatureParams.getBody());
        sortedParams.put("secret", secret); // secret 作为最后一项

        // 构造签名字符串
        StringBuilder signData = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            if (isStringBlank(entry.getValue())) {
                continue;
            }
            signData.append(entry.getKey()).append("=")
                    .append(entry.getValue()).append("\n");
        }
        String signString = signData.substring(0, signData.length() - 1); // 去掉最后的换行符

        return hmacSha256(secret, signString);
    }

    /**
     * HMAC-SHA256 加密
     */
    private static String hmacSha256(String secret, String data) {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            mac.init(secretKeySpec);
            byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));

            // 转换成十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                hexString.append(String.format("%02x", b));
            }
            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException("HMAC-SHA256 签名计算失败", e);
        }
    }

    /**
     * 判断字符串是否为空白（null或仅包含空白字符）
     *
     * @param str 字符串
     * @return true表示字符串为null或全为空白字符
     */
    public static boolean isStringBlank(String str) {
        return str == null || str.trim().isEmpty();
    }


}
